const DatabaseService = require('./db.service');
const StreamService = require('./stream.service');
const Logger = require('../utils/logger');

class DJIService {
  constructor(streamService) {
    this.activeStreams = new Map(); // Store active drone streams
    this.dbService = new DatabaseService();
    this.streamService = streamService; // 引用流服务以管理拉流任务
    
    // 测试数据库连接并恢复流配置
    this.initializeService();
  }
  
  async initializeService() {
    try {
      // 测试数据库连接
      const result = await this.dbService.testConnection();
      if (result.success) {
        Logger.info('DJIService', '数据库连接测试通过');
        
        // 获取无人机数量
        const drones = await this.dbService.getAllDrones();
        if (drones.success) {
          Logger.info('DJIService', `数据库中找到 ${drones.data.length} 个无人机`);
        }
        
        // 注意：流恢复将在流媒体服务器启动后进行
      } else {
        Logger.error('DJIService', '数据库连接测试失败', new Error(result.error));
      }
    } catch (error) {
      Logger.error('DJIService', '初始化服务时出错', error);
    }
  }
  
  async recoverActiveStreams() {
    try {
      Logger.info('DJIService', '开始恢复活动流配置...');
      
      // 查询数据库中所有活动状态的流
      const result = await this.dbService.getAllActiveStreams();
      
      if (!result.success) {
        Logger.error('DJIService', '获取活动流失败', new Error(result.error));
        return;
      }
      
      const streams = result.data;
      if (streams.length === 0) {
        Logger.info('DJIService', '数据库中没有活动流配置需要恢复');
        return;
      }
      
      Logger.info('DJIService', `找到 ${streams.length} 个活动流配置，开始恢复...`);
      
      // 逐个恢复流配置
      for (const stream of streams) {
        try {
          Logger.info('DJIService', `正在恢复流: ${stream.drone_id} <- ${stream.source_url}`);
          
          // 直接启动拉流任务（不更新数据库，因为配置已存在）
          const pullResult = this.streamService.addPullStream(stream.drone_id, stream.source_url);
          
          if (pullResult.success) {
            // 更新内存中的活动流状态
            this.activeStreams.set(stream.drone_id, {
              id: stream.drone_id,
              sourceRtmpUrl: stream.source_url,
              targetRtmpUrl: stream.rtmp_url,
              streamId: stream.id,
              startTime: new Date(stream.start_time),
              lastUpdate: new Date(),
              status: 'active',
              sourceType: stream.source_type
            });
            
            Logger.info('DJIService', `成功恢复流: ${stream.drone_id}`);
          } else {
            Logger.warn('DJIService', `恢复流失败: ${stream.drone_id} - ${pullResult.error}`);
            
            // 如果恢复失败，可以考虑将数据库中的状态更新为 inactive
            // 但这里我们先保持不变，让用户手动处理
          }
        } catch (error) {
          Logger.error('DJIService', `恢复流 ${stream.drone_id} 时出错`, error);
        }
      }
      
      const recoveredCount = this.activeStreams.size;
      Logger.info('DJIService', `流恢复完成，成功恢复 ${recoveredCount} 个流`);
      
    } catch (error) {
      Logger.error('DJIService', '恢复活动流时出错', error);
    }
  }

  /**
   * 添加拉流任务（从无人机RTMP源拉取流）
   * @param {string} droneId - 无人机唯一标识符
   * @param {string} sourceRtmpUrl - 无人机RTMP源地址
   */
  async addPullStream(droneId, sourceRtmpUrl) {
    try {
      Logger.info('DJIService', `尝试添加拉流任务: ${droneId} <- ${sourceRtmpUrl}`);
      
      // 检查是否已有该无人机的活动流
      const existingActiveStream = await this.dbService.getActiveStreamByDroneId(droneId);
      if (existingActiveStream.success && existingActiveStream.data) {
        const activeStream = existingActiveStream.data;
        
        // 如果源地址相同，直接返回成功
        if (activeStream.source_url === sourceRtmpUrl) {
          Logger.info('DJIService', `无人机 ${droneId} 已有相同源地址的活动流，无需重复添加`);
          
          // 更新内存中的活动流信息
          this.activeStreams.set(droneId, {
            id: droneId,
            sourceRtmpUrl: sourceRtmpUrl,
            targetRtmpUrl: activeStream.rtmp_url,
            streamId: activeStream.id,
            startTime: new Date(activeStream.start_time),
            lastUpdate: new Date(),
            status: 'active',
            sourceType: activeStream.source_type
          });
          
          return {
            success: true,
            message: '流已存在，无需重复添加',
            existing: true
          };
        } else {
          // 源地址不同，停止旧流，启动新流
          Logger.info('DJIService', `无人机 ${droneId} 源地址发生变化，从 ${activeStream.source_url} 更改为 ${sourceRtmpUrl}`);
          
          // 先停止旧的拉流任务
          this.streamService.removePullStream(droneId);
        }
      }
      
      // 保存无人机到数据库
      await this.dbService.addDrone(droneId);
      
      // 添加拉流任务
      const result = this.streamService.addPullStream(droneId, sourceRtmpUrl);
      
      if (result.success) {
        // 生成目标RTMP地址
        const targetRtmpUrl = `rtmp://127.0.0.1:1937/live/${droneId}`;
        
        // 添加或更新流信息到数据库（包含源地址）
        const streamResult = await this.dbService.addOrUpdateStream(
          droneId,
          droneId, // stream_name
          targetRtmpUrl, // rtmp_url (目标地址)
          sourceRtmpUrl, // source_url (源地址)
          result.sourceType // source_type (源类型)
        );
        
        if (streamResult.success) {
          const actionText = streamResult.updated ? '更新' : '添加';
          Logger.info('DJIService', `流信息已${actionText}到数据库，流ID: ${streamResult.insertId}`);
        } else {
          Logger.warn('DJIService', `保存流信息到数据库失败: ${streamResult.error}`);
        }
        
        // 记录活动流（包含源地址信息）
        this.activeStreams.set(droneId, {
          id: droneId,
          sourceRtmpUrl: sourceRtmpUrl,
          targetRtmpUrl: targetRtmpUrl,
          streamId: streamResult.insertId || null,
          startTime: new Date(),
          lastUpdate: new Date(),
          status: 'active',
          sourceType: result.sourceType
        });
        
        Logger.info('DJIService', `已添加无人机拉流任务: ${droneId} <- ${sourceRtmpUrl}`);
      } else {
        Logger.error('DJIService', `添加拉流任务失败: ${result.error}`);
      }
      
      return result;
    } catch (error) {
      Logger.error('DJIService', '添加拉流任务时出错', error);
      return {
        success: false,
        error: error.message
      };
    }
  }

  /**
   * 移除拉流任务
   * @param {string} droneId - 无人机唯一标识符
   */
  async removePullStream(droneId) {
    try {
      Logger.info('DJIService', `尝试移除拉流任务: ${droneId}`);
      
      // 移除拉流任务
      const result = this.streamService.removePullStream(droneId);
      
      if (result.success) {
        // 获取活动流信息
        const activeStream = this.activeStreams.get(droneId);
        
        // 更新数据库中的流状态
        if (activeStream && activeStream.streamId) {
          const updateResult = await this.dbService.updateStreamStatus(activeStream.streamId, 'inactive');
          if (updateResult.success) {
            Logger.info('DJIService', `数据库中流状态已更新: ${activeStream.streamId}`);
          } else {
            Logger.warn('DJIService', `更新数据库流状态失败: ${updateResult.error}`);
          }
        }
        
        // 从活动流中移除
        if (this.activeStreams.has(droneId)) {
          this.activeStreams.delete(droneId);
        }
        
        // 更新数据库状态
        await this.dbService.updateDroneStatus(droneId, 'inactive');
        
        Logger.info('DJIService', `已移除无人机拉流任务: ${droneId}`);
      } else {
        Logger.error('DJIService', `移除拉流任务失败: ${result.message}`);
      }
      
      return result;
    } catch (error) {
      Logger.error('DJIService', '移除拉流任务时出错', error);
      return {
        success: false,
        error: error.message
      };
    }
  }
  
  /**
   * 获取所有活动流信息
   */
  async getActiveStreams() {
    try {
      // 从数据库获取所有无人机
      const dbResult = await this.dbService.getAllDrones();
      if (!dbResult.success) {
        throw new Error(dbResult.error);
      }
      
      Logger.debug('DJIService', `数据库返回 ${dbResult.data.length} 个无人机`);
      
      // 获取活动流信息（包含源地址信息）
      const streams = [];
      for (let [id, stream] of this.activeStreams) {
        // 从数据库获取流详情
        let dbStreamInfo = null;
        if (stream.streamId) {
          const streamResult = await this.dbService.getStreamsByDroneId(id);
          if (streamResult.success && streamResult.data.length > 0) {
            dbStreamInfo = streamResult.data.find(s => s.id === stream.streamId);
          }
        }
        
        streams.push({
          id: stream.id,
          sourceRtmpUrl: stream.sourceRtmpUrl,
          targetRtmpUrl: stream.targetRtmpUrl,
          streamId: stream.streamId,
          startTime: stream.startTime,
          lastUpdate: stream.lastUpdate,
          status: stream.status,
          sourceType: stream.sourceType,
          // 数据库中的流信息
          dbStreamInfo: dbStreamInfo
        });
      }
      
      Logger.debug('DJIService', `活动流映射包含 ${streams.length} 个条目`);
      return streams;
    } catch (error) {
      Logger.error('DJIService', '获取活动流时出错', error);
      throw error;
    }
  }

  /**
   * 获取特定无人机流信息
   * @param {string} droneId - 无人机唯一标识符
   */
  async getDroneStream(droneId) {
    try {
      // 从数据库获取无人机
      const dbResult = await this.dbService.getDroneById(droneId);
      if (!dbResult.success) {
        throw new Error(dbResult.error);
      }
      
      // 获取活动流信息
      const stream = this.activeStreams.get(droneId) || null;
      return {
        drone: dbResult.data,
        stream: stream
      };
    } catch (error) {
      Logger.error('DJIService', '获取无人机流时出错', error);
      throw error;
    }
  }
  
  /**
   * 获取无人机流详情（包括源地址和数据库信息）
   * @param {string} droneId - 无人机唯一标识符
   */
  async getDroneStreamDetails(droneId) {
    try {
      // 获取数据库中的无人机信息
      const droneResult = await this.dbService.getDroneById(droneId);
      
      // 获取数据库中的流信息
      const streamsResult = await this.dbService.getStreamsByDroneId(droneId);
      
      // 获取内存中的活动流信息
      const activeStream = this.activeStreams.get(droneId);
      
      return {
        drone: droneResult.success ? droneResult.data : null,
        dbStreams: streamsResult.success ? streamsResult.data : [],
        activeStream: activeStream || null,
        playUrls: activeStream ? this.getStreamPlayUrls(droneId) : null
      };
    } catch (error) {
      Logger.error('DJIService', '获取无人机流详情时出错', error);
      throw error;
    }
  }
  
  // 获取流播放地址
  getStreamPlayUrls(droneId) {
    return {
      httpFlvUrl: this.streamService.getStreamPlayUrl(droneId),
      rtmpUrl: this.streamService.getRtmpPlayUrl(droneId)
    };
  }
  
  async close() {
    await this.dbService.close();
  }
}

module.exports = DJIService;